package api

import (
	"context"
	"errors"
	"go-caipu/pkg/constant"
	"os"
	"path/filepath"
	"strings"

	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"

	"go-caipu/pkg/api/helper"
	"go-caipu/pkg/api/middleware"
	"go-caipu/pkg/api/pendingFeatureCode"
	_ "go-caipu/pkg/cmd/docs"
	user2 "go-caipu/pkg/services/admin/sysuser"
)

type ModuleOpera struct {
	Module      string //操作模块
	Description string //操作描述
}

// registerRoutes registers all API HTTP routes.
func (hs *HTTPServer) registerRoutes() {

	if hs.Cfg.Application.Mode == "development" {
		gin.SetMode(gin.DebugMode)
	}

	authMiddleware := middleware.AuthMiddleware(hs.Jwt, hs.onlineService, hs.log) //check jwt
	authCheckRole := middleware.AuthCheckRole(hs.userService, hs.Jwt, hs.log)     //check user_role
	//site：（前台wek接口，鉴权由各插件自行实现）key为插件id
	site := hs.handle.Group("/site")
	{
		site.GET("/:pluginId/*url", hs.CallResource)
	}
	//本地文件访问
	hs.handle.GET("/file/*url", hs.DownLocalFileHandler)
	r := hs.handle.Group("/api")
	//前台静态
	r.GET("/user/message/unread", func(c *gin.Context) {
		helper.JSON(c, helper.Response{Success: true, Msg: "ok", Code: 200, Data: map[string]interface{}{"total": 0}})
	})
	r.GET("/sse", hs.streamSSE)
	r.GET("/captcha/image", hs.GetCaptcha)
	r.GET("/captcha/behavior", hs.GetBehaviorCaptcha)
	r.POST("/captcha/behavior", hs.CheckBehaviorCaptcha)

	r.POST("/refreshToken", hs.RefreshToken)
	r.GET("/app-config", hs.GetAppConfig)
	r.Group("/ws").GET("", pendingFeatureCode.Handler)

	common := r.Group("/common")
	{
		common.GET("/dict/option/:code", hs.GetConfigsByKey)
		common.GET("/tree/dept", hs.GetDeptTree)
		common.GET("/tree/menu", hs.GetMenuTreeSelect)
		common.GET("/dict/role", hs.GetRoleOptions)
		common.GET("/user/option", hs.GetUserOptions)
		common.GET("/user/:id", hs.GetUserDetail) //获取单个用户信息
		common.GET("/dict/:code", hs.GetDictDataOptions)
		common.GET("/social", hs.GetSocials)
		common.GET("/dept/option", hs.GetDeptOptionsHandler).Use(authMiddleware) //提供给plugin查询部门列表使用
	}
	//--=============** 上传文件  **==================================================
	upload := r.Group("/upload").Use(authMiddleware)
	{

		// 完整文件上传
		upload.POST("", hs.ValidateUploadMiddleware(), hs.Upload)

		// 分片上传相关
		upload.POST("/chunk", nil)
		upload.POST("/chunk/:uploadId", nil)
		upload.POST("/chunk/:uploadId/merge", nil)
	}
	//--=============** 下载文件（需要登录）  **========================================
	file := r.Group("/file")
	{
		//获取文件的访问URL
		file.GET("/:file_key/download", hs.GetFileUrlHandler)
		//下载文件
		file.GET("/:file_key", hs.DownLoad)
		file.DELETE("/:file_key", hs.DeleteFile).Use(authCheckRole).Use(authMiddleware) //删除文件
	}
	//--=============** 存储配置  **==================================================
	storage := r.Group("/storage").Use(authCheckRole).Use(authMiddleware)
	{
		storage.GET("/list", hs.ListStorageConfigs)
		storage.GET("/:id", hs.GetStorageConfig)
		storage.POST("", hs.CreateStorageConfig)
		storage.PUT("/:id/status", hs.UpdateStorageStatus)
		storage.PUT("/:id/default", hs.SetDefaultStorageConfig)
		storage.PUT("/:id", hs.UpdateStorageConfig)
		storage.DELETE("", hs.DeleteStorageConfig)
	}
	//--===============================================================================
	auth := r.Group("/auth")
	{
		auth.POST("/login", hs.LoginPost)
		auth.POST("/logout", hs.LogoutPost)
		auth.GET("/:source", hs.GetSocialLogin)
		auth.GET("/user/info", hs.GetUserInfo).Use(authMiddleware)
		auth.GET("/user/route", hs.GetAsyncRoutes).Use(authCheckRole)
	}

	r.GET("dashboard/notice", func(c *gin.Context) {
		c.JSON(200, []byte(`{
    "code": "0",
    "msg": "ok",
    "success": true,
    "timestamp": 1745225449041,
    "data": [
        {
            "id": 1,
            "title": "诚邀！使用公司/组织/项目登记",
            "type": "2"
        }
    ]
     }`))
	})
	profile := r.Group("/user/profile").Use(authMiddleware)
	{
		profile.PATCH("/basic/info", hs.UpdateUserBasicInfoHandler)
		profile.PATCH("/avatar", hs.UpdateAvatarHandler)
		profile.PATCH("/password", hs.UpdateUserPwd)
		//第三方登录
		profile.GET("/social", hs.GetSocials)
		profile.DELETE("/social/:source", func(c *gin.Context) {
			helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, errors.New("功能未实现"))
			return
		})
	}

	//plugins
	pluginRoute := r.Group("/plugins").Use(authCheckRole).Use(authMiddleware)
	{
		pluginRoute.GET("", hs.GetPluginList)
		pluginRoute.GET("/:pluginId", hs.GetPlugin)
		pluginRoute.POST("/:pluginId/:version/install", hs.InsertPlugin)
		pluginRoute.GET("/:pluginId/markdown/:name", hs.GetPluginMarkdown)
		pluginRoute.POST("/:pluginId/uninstall", hs.UninstallPlugin)
	}
	//plugins-route-proxy
	r.GET("/proxy/*url", hs.ProxyCnetRequest)
	//plugin
	r.GET("/plugin/health/:pluginId", hs.CheckHealth)
	r.GET("/micro-apps", hs.GetMicroApps)
	r.Any("/plugintest/:pluginId/send", hs.AsyncCallResource)
	// 调用插件路由
	r.Any("/plugin/:pluginId/*url", hs.CallResource)
	//registerPluginRoute(hs) 访问路由静态页面
	hs.handle.GET("/app/:pluginName/*url", hs.registerPluginRoute)

	//--system
	adminRoute := r.Group("/system")

	user := adminRoute.Group("/user").Use(authCheckRole).Use(authMiddleware)
	{
		user.GET("", hs.GetUserPage)
		user.GET("/:id", hs.GetUser)
		user.POST("", hs.CreateUser) //create
		user.PUT("/:id", hs.UpdateUser)
		user.DELETE("", hs.RemoveUser)
		//user.POST("/avatar", hs.UpdateAvatarHandler)
		user.PATCH("/:userId/password", hs.ResetUserPwd) //用户管理更新密码
		user.PATCH("/:userId/role", hs.UpdateUserRoleHandler)
		//user.GET("/social", func(c *gin.Context) {
		//	c.JSON(http.StatusOK, helper.Response{Code: 200, Data: "[]", Success: true})
		//}) //绑定第三方帐号信息
	}
	role := adminRoute.Group("/role").Use(authCheckRole).Use(authMiddleware)
	{
		//role.GET("", hs.GetRolePage) //暂时不支持
		role.GET("/list", hs.GetRoleList)
		role.GET("/:roleId", hs.GetRole)
		role.GET("/:roleId/user", hs.GetRoleUser)
		role.GET("/:roleId/user/id", hs.GetRoleUserId)
		role.POST("", hs.CreateRole)
		role.POST("/:roleId/user", hs.AddRoleUser) //添加角色用户
		role.PUT("/:id", hs.UpdateRole)
		role.PUT("/:id/permission", hs.UpdateRolePermission)
		role.DELETE("/:id/user", hs.RemoveRoleUser)
		role.DELETE("", hs.RemoveRole)

		role.GET("/datascope/:roleId", hs.GetRoleDataScope) //角色数据权限
		role.PUT("/datascope/:id", hs.UpdateRoleDataScope)
		role.GET("/options", hs.GetRoleOptions)
	}
	post := adminRoute.Group("/post").Use(authCheckRole).Use(authMiddleware)
	{
		post.GET("", hs.GetPostPage)
		post.GET("/:id", hs.GetPost)
		post.POST("", hs.CreatePost)
		post.PUT("/:id", hs.UpdatePost)
		post.DELETE("", hs.RemovePost)
	}

	menu := adminRoute.Group("/menu").Use(authCheckRole).Use(authMiddleware)
	{
		menu.GET("/tree", hs.GetMenuList)
		menu.GET("/:id", hs.GetMenu)
		menu.POST("", hs.CreateMenu)
		menu.PUT("/:id", hs.UpdateMenu)
		menu.DELETE("", hs.RemoveMenu)
		menu.POST("/:id/api", hs.UpdateMenuApi)
		menu.GET("/:id/export", hs.ExportMenu)

	}
	api := adminRoute.Group("/sys-api").Use(authCheckRole).Use(authMiddleware)
	{
		api.GET("", hs.GetSysApiPage)
		api.GET("/:id", hs.GetSysApi)
		api.POST("", hs.CreateSysApi)
		api.PUT("/:id", hs.UpdateSysApi)
		api.DELETE("/:id", hs.RemoveSysApi)
		api.GET("/export", hs.ExportSysApi)

		api.GET("/category", hs.GetSysApiCategory)
		api.POST("/category", hs.CreateSysApiCategory)
		api.PUT("/category/:id", hs.UpdateSysApiCategory)
		api.DELETE("/category/:id", hs.RemoveSysApiCategory)
	}
	r.GET("/menu/menurole", nil).Use(authMiddleware)

	dept := adminRoute.Group("/dept").Use(authCheckRole).Use(authMiddleware)
	{
		dept.GET("/option", hs.GetDeptOptionsHandler) //plugin查询部门列表使用
		dept.GET("/tree", hs.GetDeptTreeList)
		dept.GET("/:id", hs.GetDept)
		dept.POST("", hs.CreateDept)
		dept.PUT("/:id", hs.UpdateDept)
		dept.DELETE("", hs.RemoveDept)
		dept.DELETE("/:id", hs.RemoveDeptByIds)

	}
	//dict
	dict := adminRoute.Group("/dict").Use(authCheckRole).Use(authMiddleware)
	{
		dict.GET("/list", hs.GetSysDictTypePage)
		dict.GET("/:id", hs.GetSysDictType)
		dict.POST("", hs.CreateSysDictType)
		dict.PUT("/:id", hs.UpdateSysDictType)
		dict.DELETE("", hs.RemoveSysDictType)

		dict.GET("/item", hs.GetSysDictDataPage)
		dict.GET("/item/:id", hs.GetSysDictData)
		dict.POST("/item", hs.CreateSysDictData)
		dict.PUT("/item/:id", hs.UpdateSysDictData)
		dict.DELETE("/item", hs.RemoveSysDictData)
	}

	config := adminRoute.Group("/option").Use(authCheckRole).Use(authMiddleware)
	{
		config.GET("", hs.GetConfigMap) //get系统设置
		config.GET("list", hs.GetSysConfigPage)
		config.GET("/:id", hs.GetSysConfig)
		config.POST("", hs.CreateSysConfig)
		config.PUT("/:id", hs.UpdateSysConfig) //单个更新
		config.PUT("", hs.SetSystemConfig)     //系统设置批量更新
		config.DELETE("", hs.RemoveSysConfig)
	}
	//code-tools
	toolsDb := adminRoute.Group("/db").Use(authMiddleware).Use(authCheckRole)
	{
		toolsDb.GET("/columns/page", hs.GetDBColumnPage) //查询表的字段
	}
	sysTable := adminRoute.Group("/sys").Use(authMiddleware).Use(authCheckRole)
	{
		sysTable.PUT("/table/todb/:id", hs.GenDBHandler) //生成数据库数据
	}
	codeTable := r.Group("/code/generator").Use(authMiddleware).Use(authCheckRole)
	{
		codeTable.GET("/db/table", hs.GetDBTablePage)                  //查询【数据库】表
		codeTable.GET("/config", hs.GetSysTablePage)                   //查询选择的表
		codeTable.POST("/table/import", hs.InsertSysTables)            //导入选择表格
		codeTable.DELETE("/table", hs.RemoveSysTable)                  //删除选择的表
		codeTable.GET("/config/:tableName", hs.GetSysTableByTableName) //根据表名查询表和字段信息
		codeTable.PUT("/table", hs.UpdateSysTable)                     //更新表信息和列内容
		// codeTable.GET("/table/:id", wrapper.HandlerFunc(hs.log, hs.GetSysTable))                   //暂时未使用
		codeTable.GET("/preview/:id", hs.PreviewCode) //生成结果预览
		//sysTable.PUT("/table/todb/:id", wrapper.HandlerFunc(hs.log, hs.GenDBHandler)) //生成数据库数据
	}
	//ds-数据源管理
	datasource := adminRoute.Group("/ds").Use(authMiddleware).Use(authCheckRole)
	{
		datasource.GET("", hs.GetDatasourcePage)
		datasource.GET("/:name", hs.GetDatasource)
		datasource.POST("", hs.CreateDatasource)
		datasource.PUT("/:id", hs.UpdateDatasource)
		datasource.DELETE("", hs.RemoveDatasource)
		// datasource.GET("/:name/health", hs.CheckDataSourceHealth)
	}
	monitor := r.Group("/monitor").Use(authCheckRole).Use(authMiddleware)
	{
		monitor.GET("/online", hs.GetOnlineUser)
		monitor.DELETE("/online/:token", hs.Kickout)
	}
	//log
	SystemLog := adminRoute.Group("/log").Use(authCheckRole).Use(authMiddleware)
	{
		SystemLog.GET("", hs.GetOperaLogHandle)
		//SystemLog.GET("/login/:id", wrapper.HandlerFunc(hs.log, hs.GetSysLoginLog))
		//SystemLog.POST("/login", wrapper.HandlerFunc(hs.log, hs.CreateSysLoginLog))
		//SystemLog.PUT("/login/:id", wrapper.HandlerFunc(hs.log, hs.UpdateSysLoginLog))
		//SystemLog.DELETE("/login", wrapper.HandlerFunc(hs.log, hs.RemoveSysLoginLog))
		SystemLog.GET("/:id", hs.GetSysOperalog)
	}
	sysjob := adminRoute.Group("/sysjob").Use(authCheckRole).Use(authMiddleware)
	{
		sysjob.GET("", hs.GetSysJobPage)
		sysjob.GET("/:id", hs.GetSysJob)
		sysjob.POST("", hs.CreateSysJob)
		sysjob.PUT("/:id", hs.UpdateSysJob)
		sysjob.DELETE("/:id", hs.RemoveSysJob)
		sysjob.PATCH("/:id/status", nil)
		sysjob.GET("/log", hs.GetSysJobLogPage)
	}

	if hs.Cfg.Application.Mode == "development" || hs.Cfg.Application.Mode == "demo" {
		hs.handle.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	}
	//main-site 兜底
	//hs.handle.NoRoute(func(c *gin.Context) {
	//	path := c.Request.URL.Path // 获取请求路径
	//	s := strings.Split(path, ".")
	//	// 分割路径，获取文件后缀
	//	prefix := "dist"                                                   // 前缀路径
	//	if data, err := caipu.Static.ReadFile(prefix + path); err != nil { // 读取文件内容
	//		// 如果文件不存在，返回首页 index.html
	//		if data, err = caipu.Static.ReadFile(prefix + "/index.html"); err != nil {
	//			c.JSON(404, gin.H{
	//				"err": err,
	//			})
	//		} else {
	//			c.Data(200, mime.TypeByExtension(fmt.Sprintf(".%s", s[len(s)-1])), data)
	//		}
	//	} else {
	//		// 如果文件存在，根据请求的文件后缀，设置正确的mime type，并返回文件内容
	//		c.Data(200, mime.TypeByExtension(fmt.Sprintf(".%s", s[len(s)-1])), data)
	//	}
	//})
}

func (hs *HTTPServer) getJwtUserID(ctx *gin.Context) int64 {
	tokenString := ctx.Request.Header.Get("Authorization")
	if tokenString == "" {
		hs.log.Warn("请求未携带token，无权限访问: url:%s,params: %s", ctx.Request.URL, ctx.Params)
		return 0
	}
	claims, err := hs.Jwt.ParseToken(tokenString)
	if err != nil {
		hs.log.Error("jwt error: url:%s,params: %s", ctx.Request.URL, ctx.Params)
		return 0
	}
	return claims.UserId
}
func (hs *HTTPServer) registerPluginRoute(c *gin.Context) {
	url := c.Param("url")
	pluginName := c.Param("pluginName")
	//path := c.Request.URL.Path // example:/plugin/x
	pluginPath := filepath.Join(hs.Cfg.Application.PluginsPath, pluginName, "web")
	// 处理文件不存在的情况 或者 扩展名
	s := strings.Split(url, ".")
	if _, err := os.Stat(pluginPath); err != nil || len(s) <= 1 {
		c.File(filepath.Join(pluginPath, "index.html"))
		return
	}
	c.File(filepath.Join(pluginPath, url))
}
func (hs *HTTPServer) getUserName(userId int64) string {
	user, err := hs.userService.GetUser(context.Background(), user2.GetUserCommand{UserId: userId})
	if err != nil {
		return ""
	}
	return user.NickName
}
